home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagd_f.zip / DRIVES.SWG / 0097_IDE HDD Parameters?.pas < prev   
Pascal/Delphi Source File  |  1995-02-28  |  4KB  |  149 lines

  1. {
  2.  RP> Has anyone any ideas how to interrogate an IDE drive to get
  3.  RP> its setup parameters
  4. }
  5.  
  6. { Read IDE drive info, Arne de Bruijn, 1994, PD }
  7. { Information from 'Alles over PC Hardware' by Hans-Peter Messmer }
  8.  
  9. {$G+}
  10. uses Crt,Dos;
  11.  
  12. var
  13.  Buffer:pointer;
  14. { Buffer filled with following information (word offsets):
  15.   0 configuration:
  16.     bit 0 reserved
  17.         1 1=hard-sector drive
  18.         2 1=soft-sector drive
  19.         3 1=RLL/ARLL format
  20.         4 1=headswitchdelay is 15 ms
  21.         5 1=less currency mode implented
  22.         6 1=hard disk
  23.         7 1=exchangable medium (mostly CD-ROM drive)
  24.         8 1=internal datatransfer <5 Mbit/s
  25.         9 1=internal datatransfer between 5 and 10 Mbit/s
  26.        10 1=internal datatransfer >10 Mbit/s
  27.        11 1=rotation speed toleration >0,5% (notebook)
  28.        12-15 reserved
  29.   1 no of physical cylinders
  30.   2 reserved
  31.   3 no of heads
  32.   4 no of not-formatted bytes per physical sector
  33.   5 no of not-formatted bytes per sector
  34.   6 no of physical sectors
  35.   7-9 reserved for manufacturer
  36.  10-19 ASCII serial number
  37.  20 buffertype (01h one-directional, 02h bi-directional, 03h=cache buffer)
  38.  21 buffersize/512
  39.  22 no of ECC bytes transferred at read/writelong cmds
  40.  23-26 ASCII controller-firmware ID
  41.  27-46 ASCII modelnumber
  42.  47 bit 0..7 no of sectors between two interrupts, bit 8..15 reserved
  43.  48 bit 0: 1=32 bit-I/O, 0 no 32 bit-I/O, bit 1..7 reserved
  44.  49 bit 0..7 reserved, bit 8: 1=DMA, 0=no DMA, bit 9: 1=LBA, 0=no LBA
  45.  50 reserved
  46.  51 bit 0..7 reserved, bit 8..15 PIO cyclus time
  47.     (0=600ns, 1=380ns, 2=240ns, 3=180ns)
  48.  52 bit 0..7 reserved, bit 8..15 DMA cyclus time
  49.     (0=960ns, 1=380ns, 2=240ns, 3=150ns)
  50.  53 reserved
  51.  54 no of logical cylinders
  52.  55 no of logical heads
  53.  56 no of logical sectors per track
  54.  57-58 Bytes per logical sector
  55.  59 bit 0..7 no of sectors
  56.  60-61 addressable sectors in LBA mode
  57.  62 single DMA: bit 0..7=supported modes, bit 8..15=active modes
  58.  63 multiple DMA: bit 0..7=supported modes, bit 8..15=active modes
  59.  64-127 reserved
  60.  128-159 manufacturer specific
  61.  160-255 reserved
  62. }
  63.  GotData:boolean;
  64.  
  65. function SwitchChars(var X; Len:byte):string; assembler;
  66. { Returns Len bytes from X, each word swapped }
  67. asm
  68.  push ds
  69.  les di,@Result
  70.  xor ah,ah
  71.  mov al,Len
  72.  mov cx,ax
  73.  shl al,1
  74.  stosb
  75.  jcxz @NoCopy
  76.  lds si,X
  77. @Copy:
  78.  lodsw
  79.  xchg al,ah
  80.  stosw
  81.  loop @Copy
  82. @NoCopy:
  83.  pop ds
  84. end;
  85.  
  86. procedure HDInt; interrupt;
  87. { Interrupt called when data is ready }
  88. begin
  89.  if Port[$1f7] and 8<>0 then
  90.   begin
  91.    asm
  92.     mov dx,1f0h
  93.     les di,Buffer
  94.     mov cx,256
  95.     rep insw            { Get 256 words (512 bytes) }
  96.    end;
  97.    GotData:=true;
  98.   end;
  99.  Port[$a0]:=$20;        { Send EOI to PIC 2 }
  100.  Port[$20]:=$20;        { Send EOI to PIC 1 }
  101. end;
  102.  
  103. type
  104.  AWord=array[0..32766] of word;
  105. var
  106.  Timer:longint absolute $40:$6c;
  107.  Slave:boolean;
  108.  LastTimer,T:byte;
  109.  OldInt:pointer;
  110.  OldPic1M,OldPic2M:byte;
  111. begin
  112.  Clrscr;
  113.  Slave:=false; { True is check for slave, false check for master }
  114.  GetMem(Buffer,512);
  115.  T:=2;         { Wait 2 clock ticks }
  116.  while (Port[$1f7] and $c0<>$40) and (T>0) do
  117.   if byte(Timer)<>LastTimer then begin Dec(T); LastTimer:=byte(Timer); end;
  118.  if Port[$1f7] and $c0<>$40 then
  119.   begin
  120.    WriteLn('Timeout 1!');
  121.    Halt(1);
  122.   end;
  123.  GetIntVec($76,OldInt);   { Set interrupt (IRQ 14 = int $76) }
  124.  SetIntVec($76,@HDInt);
  125.  OldPic1M:=Port[$21]; OldPic2M:=Port[$a1]; { Save PIC masks }
  126.  Port[$21]:=OldPic1M and (not 4);   { Enable IRQ 14 }
  127.  Port[$a1]:=OldPic2M and (not 64);
  128.  GotData:=false;
  129.  Port[$1f6]:=$a0+byte(Slave)*16;    { Send drive no }
  130.  Port[$1f7]:=$EC;                   { Send command code }
  131.  T:=3;
  132.  while (not GotData) and (T>0) do
  133.   if byte(Timer)<>LastTimer then begin Dec(T); LastTimer:=byte(Timer); end;
  134.  Port[$21]:=OldPic1M; Port[$a1]:=OldPic2M; { Restore PIC masks }
  135.  SetIntVec($76,OldInt);   { Restore interrupt }
  136.  if not GotData then
  137.   begin
  138.    WriteLn('Timeout 2!');
  139.    Halt(1);
  140.   end;
  141.  WriteLn('Heads:',AWord(Buffer^)[3],' Cylinders:',AWord(Buffer^)[1],
  142.   ' Sectors:',AWord(Buffer^)[6]);
  143.  WriteLn('Serial number:',SwitchChars(AWord(Buffer^)[10],10));
  144.  WriteLn('Controller firmware ID:',SwitchChars(AWord(Buffer^)[23],4));
  145.  WriteLn('Modelnumber:',SwitchChars(AWord(Buffer^)[27],20));
  146.  Port[$1F6]:=$a0+byte(Slave)*16;
  147.  FreeMem(Buffer,512);
  148. end.
  149.